fsck: Move most commit processing into helper function
authorColin Walters <walters@verbum.org>
Sun, 12 Jun 2022 14:53:09 +0000 (10:53 -0400)
committerColin Walters <walters@verbum.org>
Sun, 12 Jun 2022 14:57:27 +0000 (10:57 -0400)
The inner loop was way too long; split out most of the heavy
lifting around backrefs and tombstones into a helper function.

src/ostree/ot-builtin-fsck.c

index 2c104c9e467b5bf27e192acd6288ee282e8cb6a6..0e95ae9c51058811dd81dc731e10563550d5544e 100644 (file)
@@ -229,6 +229,100 @@ fsck_commit_for_ref (OstreeRepo    *repo,
   return TRUE;
 }
 
+static gboolean
+fsck_one_commit (OstreeRepo *repo, const char *checksum, GVariant *commit, GPtrArray *tombstones,
+                 GCancellable *cancellable, GError **error)
+{
+  /* If requested, check that all the refs listed in the ref-bindings
+   * for this commit resolve back to this commit. */
+  if (opt_verify_back_refs)
+    {
+      g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0);
+      const char *collection_id = NULL;
+      if (!g_variant_lookup (metadata,
+                             OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
+                             "&s",
+                             &collection_id))
+        collection_id = NULL;
+      g_autofree const char **refs = NULL;
+      if (g_variant_lookup (metadata,
+                            OSTREE_COMMIT_META_KEY_REF_BINDING,
+                            "^a&s",
+                            &refs))
+        {
+          for (const char **iter = refs; *iter != NULL; ++iter)
+            {
+              g_autofree char *checksum_for_ref = NULL;
+              if (collection_id != NULL)
+                {
+                  const OstreeCollectionRef collection_ref = { (char *) collection_id, (char *) *iter };
+                  if (!ostree_repo_resolve_collection_ref (repo, &collection_ref,
+                                                           TRUE,
+                                                           OSTREE_REPO_RESOLVE_REV_EXT_NONE,
+                                                           &checksum_for_ref,
+                                                           cancellable,
+                                                           error))
+                    return FALSE;
+                }
+              else
+                {
+                  if (!ostree_repo_resolve_rev (repo, *iter, TRUE,
+                                                &checksum_for_ref, error))
+                    return FALSE;
+                }
+              if (checksum_for_ref == NULL)
+                {
+                  if (collection_id != NULL)
+                    return glnx_throw (error,
+                                       "Collection–ref (%s, %s) in bindings for commit %s does not exist",
+                                       collection_id, *iter, checksum);
+                  else
+                    return glnx_throw (error,
+                                       "Ref ‘%s’ in bindings for commit %s does not exist",
+                                       *iter, checksum);
+                }
+              else if (g_strcmp0 (checksum_for_ref, checksum) != 0)
+                {
+                  if (collection_id != NULL)
+                    return glnx_throw (error,
+                                       "Collection–ref (%s, %s) in bindings for commit %s does not resolve to that commit",
+                                       collection_id, *iter, checksum);
+                  else
+                    return glnx_throw (error,
+                                       "Ref ‘%s’ in bindings for commit %s does not resolve to that commit",
+                                       *iter, checksum);
+                }
+            }
+        }
+    }
+
+  if (opt_add_tombstones)
+    {
+      GError *local_error = NULL;
+      g_autofree char *parent = ostree_commit_get_parent (commit);
+      if (parent)
+        {
+          g_autoptr(GVariant) parent_commit = NULL;
+          if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent,
+                                         &parent_commit, &local_error))
+            {
+              if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+                {
+                  g_ptr_array_add (tombstones, g_strdup (checksum));
+                  g_clear_error (&local_error);
+                }
+              else
+                {
+                  g_propagate_error (error, local_error);
+                  return FALSE;
+                }
+            }
+        }
+    }
+
+  return TRUE;
+}
+
 gboolean
 ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
 {
@@ -316,91 +410,10 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation,
 
       if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, error))
         return FALSE;
-      /* If requested, check that all the refs listed in the ref-bindings
-       * for this commit resolve back to this commit. */
-      if (opt_verify_back_refs)
-        {
-          g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0);
-          const char *collection_id = NULL;
-          if (!g_variant_lookup (metadata,
-                                 OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
-                                 "&s",
-                                 &collection_id))
-            collection_id = NULL;
-          g_autofree const char **refs = NULL;
-          if (g_variant_lookup (metadata,
-                                OSTREE_COMMIT_META_KEY_REF_BINDING,
-                                "^a&s",
-                                &refs))
-            {
-              for (const char **iter = refs; *iter != NULL; ++iter)
-                {
-                  g_autofree char *checksum_for_ref = NULL;
-                  if (collection_id != NULL)
-                    {
-                      const OstreeCollectionRef collection_ref = { (char *) collection_id, (char *) *iter };
-                      if (!ostree_repo_resolve_collection_ref (repo, &collection_ref,
-                                                               TRUE,
-                                                               OSTREE_REPO_RESOLVE_REV_EXT_NONE,
-                                                               &checksum_for_ref,
-                                                               cancellable,
-                                                               error))
-                        return FALSE;
-                    }
-                  else
-                    {
-                      if (!ostree_repo_resolve_rev (repo, *iter, TRUE,
-                                                    &checksum_for_ref, error))
-                        return FALSE;
-                    }
-                  if (checksum_for_ref == NULL)
-                    {
-                      if (collection_id != NULL)
-                        return glnx_throw (error,
-                                           "Collection–ref (%s, %s) in bindings for commit %s does not exist",
-                                           collection_id, *iter, checksum);
-                      else
-                        return glnx_throw (error,
-                                           "Ref ‘%s’ in bindings for commit %s does not exist",
-                                           *iter, checksum);
-                    }
-                  else if (g_strcmp0 (checksum_for_ref, checksum) != 0)
-                    {
-                      if (collection_id != NULL)
-                        return glnx_throw (error,
-                                           "Collection–ref (%s, %s) in bindings for commit %s does not resolve to that commit",
-                                           collection_id, *iter, checksum);
-                      else
-                        return glnx_throw (error,
-                                           "Ref ‘%s’ in bindings for commit %s does not resolve to that commit",
-                                           *iter, checksum);
-                    }
-                }
-            }
-        }
-      if (opt_add_tombstones)
-        {
-          GError *local_error = NULL;
-          g_autofree char *parent = ostree_commit_get_parent (commit);
-          if (parent)
-            {
-              g_autoptr(GVariant) parent_commit = NULL;
-              if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent,
-                                             &parent_commit, &local_error))
-                {
-                  if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-                    {
-                      g_ptr_array_add (tombstones, g_strdup (checksum));
-                      g_clear_error (&local_error);
-                    }
-                  else
-                    {
-                      g_propagate_error (error, local_error);
-                      return FALSE;
-                    }
-                }
-            }
-        }
+
+      if (!fsck_one_commit (repo, checksum, commit, tombstones, cancellable, error))
+        return FALSE;
+
       if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL)
         {
           n_partial++;